package com.wmx.thymeleafapp.listeners;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.listener.KeyExpirationEventMessageListener;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.stereotype.Component;

/**
 * Redis 缓存 Key 过期监听器
 * Spring Data Redis 专门提供了一个密钥过期事件消息侦听器：KeyExpirationEventMessageListener，
 * 自定义监听器类继承它，然后覆写 doHandleMessage(Message message) 方法即可。
 *
 * @author wangMaoXiong
 * @version 1.0
 * @date 2023/11/17 17:37
 */
@Component
public class KeyExpireListener extends KeyExpirationEventMessageListener {

    private static final Logger logger = LoggerFactory.getLogger(KeyExpireListener.class);

    /**
     * 通过构造函数注入 RedisMessageListenerContainer 给 KeyExpirationEventMessageListener
     *
     * @param listenerContainer ： Redis消息侦听器容器
     */
    public KeyExpireListener(RedisMessageListenerContainer listenerContainer) {
        super(listenerContainer);
    }

    /**
     * doHandleMessage 方法用于处理 Redis Key 过期通知事件，
     * 在 Redis Key 过期事件中，「只能获取到已过期的 Key 的名称，不能获取到值。」
     *
     * @param message：通知消息，只有 2 属性，分别表示消息正文（在这里就是过期的 Key 名称）以及来自于哪个 channel。
     */
    @Override
    public void doHandleMessage(Message message) {
        // 过期的 key
        String key = new String(message.getBody());
        // 消息通道
        String channel = new String(message.getChannel());

        // 过期key=h 消息通道(channel)=__keyevent@0__:expired
        // 过期key=h2 消息通道(channel)=__keyevent@0__:expired
        logger.info("过期key={} 消息通道(channel)={}", key, channel);
    }
}